import React, { Component } from 'react'
import Header from './components/Header/Header'
import List from './components/List/List'
import Footer from './components/Footer/Footer'
import './App.css'
export default class App extends Component {
  state = {
    // 状态提升: 多个组件要用到的同一份状态数据,定义到他们的公共父组件中
    // 一打开页面,就应该立刻将本地缓存的数据拿出来赋值给组件的状态
    // 注意: 本地缓存中存储的是字符串,所以一定要转成js对象
    // 注意: 如果用户第一次访问任务列表,则本地缓存中一定没有todos这个键,导致拿到的数据是null,我们就需要给todos一个空数组的默认值
    todos: JSON.parse(localStorage.getItem('todos')) || [],
    // 这个状态用于记录到底哪个Item组件要展示文本框. editId的值是对应要展示文本框的Item组件所对应的数据的id或者是undefined.
    // 每一个Item组件都要拿到这个editId,和自己的id进行比较,如果相同则展示文本框,如果不同则展示复选框和任务名,其中有一中情况就是所有Item组件都不展示文本框. 这种情况下editId的值为undefined
    editId: undefined,
  }

  // 添加任务
  addTodo = (todoName) => {
    // console.log(todoName)
    // 根据任务名创建任务对象
    const todo = {
      id: Date.now(),
      todoName,
      isDone: false,
    }

    // 要将这个任务对象,添加到todos状态里面
    // this.state.todos.push(todo) 按照规范不建议这样直接修改数据
    // 根据旧数据创建新数据
    const newTodos = [...this.state.todos]
    // 修改新数据
    newTodos.push(todo)
    this.setState({
      todos: newTodos,
    })
  }

  // 修改任务状态
  updateTodo = (id) => {
    // console.log(id)
    const newTodos = this.state.todos.map((item) => {
      if (item.id === id) {
        item.isDone = !item.isDone
      }
      return item
    })

    this.setState({
      todos: newTodos,
    })
  }

  // 删除一条任务数据
  delTodo = (id) => {
    const newTodos = this.state.todos.filter((item) => {
      // 遍历过程中,如果返回值是true,则当前一条数据会添加到新数组中,如果返回false,则当前一条数据不会添加到新数组中(被过滤了)
      // if (item.id === id) {
      //   return false
      // } else {
      //   return true
      // }
      return item.id !== id
    })
    this.setState({
      todos: newTodos,
    })
  }

  // 批量修改任务状态
  updateTodos = (target) => {
    const newTodos = this.state.todos.map((item) => {
      item.isDone = target
      return item
    })
    this.setState({
      todos: newTodos,
    })
  }

  // 清除所有已完成任务
  clearAllDoneTodos = () => {
    // 将数据中,已经完成的任务过滤掉
    const newTodos = this.state.todos.filter((item) => !item.isDone)
    this.setState({
      todos: newTodos,
    })
  }
  //修改editId的函数
  // setEditId = (id) => {
  //   // console.log(id)
  //   this.setState({
  //     editId: id,
  //   })
  // }
  setEditId = (id) => this.setState({ editId: id })

  // 编辑功能,修改任务名的函数
  editTodoName = (todoName) => {
    // console.log(todoName)
    const newTodos = this.state.todos.map((item) => {
      if (item.id === this.state.editId) {
        item.todoName = todoName
      }
      return item
    })
    this.setState({
      todos: newTodos,
      editId: undefined, //这一步不能少,不然Item组件里面,还是展示修改的文本框,数据修改完毕之后,需要让修改文本框隐藏
    })
  }
  render() {
    const { todos } = this.state

    // 所以修改数据的函数,都会执行setState,就会导致组件更新,触发render函数.所以将存储数据到本地缓存的操作写在这里
    // 注意: localStorage只能存储字符串,所以一定要将我们的数据转成json字符串再存储
    localStorage.setItem('todos', JSON.stringify(todos))
    return (
      <div className="todo-container">
        <div className="todo-wrap">
          <Header addTodo={this.addTodo}></Header>
          {/* 如果没有任务数据,则展示提示文本.如果有任务数据则展示List和Footer */}
          {todos.length ? (
            <div>
              {/* 利用props,将List需要的数据,传递下去 */}
              <List
                list={todos}
                updateTodo={this.updateTodo}
                delTodo={this.delTodo}
                editId={this.state.editId}
                setEditId={this.setEditId}
                editTodoName={this.editTodoName}
              ></List>
              <Footer
                todos={todos}
                updateTodos={this.updateTodos}
                clearAllDoneTodos={this.clearAllDoneTodos}
              ></Footer>
            </div>
          ) : (
            <h1>暂无任务!</h1>
          )}
        </div>
      </div>
    )
  }
}
